package org.lex.net;

import java.util.Arrays;

import javax.security.auth.Destroyable;

public class Password implements Destroyable {
	/*
	 * EMPTY_ARRAY has to be initialized before ANONYMOUS/LIST...etc., because
	 * EMPTY_ARRAY is referenced in constructor
	 */
	private static final char[] EMPTY_ARRAY = new char[0];
	public static final Password ANONYMOUS = new Password("anonymous", "anonymous@mail.org".toCharArray());
	public static final Password LIST = new Password("list", "list".toCharArray());
	public static final Password UPLOAD = new Password("upload", "upload".toCharArray());
	public static final Password NONE = new Password("", "".toCharArray());
	// ===================================================
	private boolean isDestroyed = false;
	private String userName = "";
	private char[] password = EMPTY_ARRAY;

	/**
	 * Creates a new <code>Password</code> object from the given user name and
	 * password.
	 * <p>
	 * Note that the given user password is copied before it is stored in the
	 * new <code>Password</code> object.It is the caller's responsibility to
	 * zero out the password information after it is no longer needed.
	 * 
	 * @param userName
	 *            the user name
	 * @param passwd
	 *            the user's password
	 */
	public Password(String userName, char[] passwd) {
		this(userName, passwd, true);
	}

	public Password(String userName, char[] passwd, boolean zeroOut) {
		this.userName = userName;
		if (null == passwd || 0 == passwd.length) {
			passwd = EMPTY_ARRAY;
		}
		this.password = Arrays.copyOf(passwd, passwd.length);
		if (true == zeroOut)
			Arrays.fill(passwd, '\0');
	}

	public char[] getPassword() {
		return password;
	}

	public String getUserName() {
		return userName;
	}

	/**
	 * Destory this <code>Password</code> object.
	 */
	public void destroy() {
		Arrays.fill(this.password, '\0');
		this.password = EMPTY_ARRAY;
		this.isDestroyed = true;
	}

	public boolean isDestroyed() {
		return this.isDestroyed;
	}

	public boolean equals(Object o) {
		if (null == o)
			return false;
		if (this == o)
			return true;
		if (false == o instanceof Password)
			return false;
		Password pd = (Password) o;
		if (false == this.userName.equals(pd.userName))
			return false;
		if (this.password.length != pd.password.length)
			return false;
		for (int i = 0; i < password.length; i++)
			if (password[i] != pd.password[i])
				return false;
		return true;
	}
}
